package com.zilue.security.service;

import com.zilue.security.util.base64.Base64Util;
import com.zilue.security.util.rsa.RSAUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by zilue on 2017/1/17.
 */
public abstract class RsaPublicKeyAbstractService extends RsaService {
    public static Logger logger = LoggerFactory.getLogger("security-client");

    private String publicKey;

    /**
     * 加密方式签名（公钥）
     *
     * @param paramterMap
     * @return
     */
    public Map<String, String> signByPublicKey(Map<String, String> paramterMap) {
        try {
            byte[] publicStr = RSAUtil.encryptByPublicKey(getDigest(paramterMap), getPublicKey());
            String sign = Base64Util.encodeByte(publicStr);
            paramterMap.put(this.sign, sign);
        } catch (Exception e) {
            logger.error("公钥加密签名异常：", e);
        }
        return paramterMap;
    }

    /**
     * 加密方式验证签名（公钥）
     *
     * @param paramterMap
     * @return
     */
    public boolean verifyByPublicKey(Map<String, String> paramterMap) {
        if (!this.status)
            return true;
        try {
            //1.取出签名参数
            String signParamter = paramterMap.get(this.sign);

            //2.复制一个map，移除签名
            Map<String, String> map = new HashMap<String, String>();
            map.putAll(paramterMap);
            map.remove(this.sign);

            //3.将签名解密成原文
            byte[] bytes = Base64Util.decodeByte(signParamter);
            byte[] privateStrAfter = RSAUtil.decryptByPublicKey(bytes, getPublicKey());

            //4.比对原文和摘要原文
            if (new String(privateStrAfter).equals(getDigest(map)))
                return true;
            else
                return false;
        } catch (Exception e) {
            logger.error("公钥解密签名异常：", e);
            return false;
        }
    }

    /**
     * 验证数字签名（数字签名只允许私钥签名，公钥验签）
     *
     * @param paramterMap
     * @return
     */
    public boolean verifyDigitalSignature(Map<String, String> paramterMap) {
        try {
            //1.取出签名参数
            String signParamter = paramterMap.get(this.sign);
            //2.复制一个map，移除签名
            Map<String, String> map = new HashMap<String, String>();
            map.putAll(paramterMap);
            map.remove(this.sign);
            //3.验证数字签名
            return RSAUtil.verify(getDigest(map).getBytes(), getPublicKey(), signParamter);
        } catch (Exception e) {
            logger.error("公钥验证数字签名异常：", e);
            return false;
        }
    }


    /**
     * 从参数中获取摘要的算法
     *
     * @param paramterMap
     * @return
     */
    public abstract String getDigest(Map<String, String> paramterMap);

    public String getPublicKey() {
        if (publicKey == null)
            logger.error("未配置公钥，请配置公钥！！");
        return publicKey;
    }

    public void setPublicKey(String publicKey) {
        this.publicKey = publicKey;
    }


}
